package com.duojuhe.coremodule.sms.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.Result;
import com.duojuhe.common.utils.encryption.md5.MD5Util;
import com.duojuhe.common.utils.regexutil.RegexUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 短信工具类
 *
 * @date 2018/08/07
 */
@Slf4j
public class SMSUtil {
    /**
     * http请求连接池
     */
    private static OkHttpClient client;

    static {
        //短信通知http连接池配置
        ConnectionPool pool = new ConnectionPool(1, 60 * 3, TimeUnit.SECONDS);
        client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .connectionPool(pool)
                .followRedirects(false)
                .retryOnConnectionFailure(true)
                .build();
    }

    /**
     * 发送短信
     * 模版： https://dx.ipyy.net/smsJson.aspx?action=send&account=4444444&password=898989898989&sendTime=
     *
     * @param mobile   手机号码，以逗号分割
     * @param content  发送内容
     * @param account  华信用户名
     * @param password 华信密码
     */
    public static Result huaXinSendSms(String mobile, String content, String account, String password, String sendIp, Integer ipSendSmsSum) {
        try {
            if (StringUtils.isEmpty(sendIp)) {
                log.info("【华信短信】发送IP地址获取失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，发送IP地址获取失败!");
            }
            if (StringUtils.isBlank(password) || StringUtils.isBlank(account)) {
                log.info("【华信短信】短信平台账号密码配置错误, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，短信平台账号密码配置错误!");
            }

            if (StringUtils.isBlank(mobile) || StringUtils.isBlank(content)) {
                log.info("【华信短信】手机号码和短信内容不可为空, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，手机号码和短信内容不可为空!");
            }
            if (!RegexUtil.isMobile(mobile.trim())) {
                log.info("【华信短信】手机号码错误，发送失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，手机号码错误!");
            }
            String passwordMD5 = MD5Util.getMD532(password);
            RequestBody body = new FormBody.Builder()
                    .add("action", "send")
                    .add("account", account)
                    .add("password", passwordMD5)
                    .add("mobile", mobile)
                    .add("content", content)
                    .build();
            Request request = new Request.Builder()
                    .url("https://dx.ipyy.net/smsJson.aspx")
                    .post(body)
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                if (responseBody != null) {
                    String resultStr = responseBody.string();
                    JSONObject jsonObject = JSON.parseObject(resultStr);
                    String successCounts = jsonObject.getString("successCounts");
                    if (StringUtils.equals(String.valueOf(mobile.split(",").length), successCounts)) {
                        log.info("【华信短信】发送成功, 手机号码：" + mobile + ",发送内容： " + content + ",返回值：" + resultStr);
                        return Result.ok("发送成功【华信】");
                    }
                    String message = jsonObject.getString("message");
                    log.info("【华信短信】发送失败, 手机号码：" + mobile + ",发送内容： " + content + ",返回值：" + resultStr);
                    return Result.fail("发送失败，" + message + "【华信】");
                }
            }
            log.info("【华信短信】发送失败, 手机号码：" + mobile + ",发送内容： " + content);
            return Result.fail("发送失败，发送出现异常【华信】");
        } catch (Exception e) {
            log.info("【华信短信】短信发送出现异常, 手机号码：" + mobile + ",发送内容： " + content);
            log.error("【华信短信】发送出现异常, mobile={}, content={}", mobile, content, e);
            return Result.fail(ErrorCodes.SMS_REQUEST_ERROR);
        }
    }


    /**
     * 阿里云 发送短信
     * 模版： https://dysmsapi.aliyuncs.com/?Action=SendSms
     *
     * @param mobile        手机号码，以逗号分割 上限1000
     * @param templateParam 发送内容 json格式
     * @param account       用户名
     * @param password      密码
     */
    public static Result aliYunSendSms(String mobile, String templateCode, String templateParam, String account, String password, String smsSign, String sendIp, Integer ipSendSmsSum) {
        try {
            if (StringUtils.isEmpty(sendIp)) {
                log.info("【阿里云短信】发送IP地址获取失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，发送IP地址获取失败!");
            }
            if (StringUtils.isEmpty(smsSign)) {
                log.info("【阿里云短信】短信签名配置错误, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，短信签名配置错误!");
            }
            if (StringUtils.isBlank(password) || StringUtils.isBlank(account)) {
                log.info("【阿里云短信】短信平台账号密码配置错误, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，短信平台账号密码配置错误!");
            }
            if (StringUtils.isBlank(templateCode)) {
                log.info("【阿里云短信】短信模板CODE不可为空, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，短信模板CODE不可为空!");
            }
            if (StringUtils.isBlank(mobile)) {
                log.info("【阿里云短信】手机号码不可为空, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，手机号码不可为空!");
            }
            if (!RegexUtil.isMobile(mobile.trim())) {
                log.info("【阿里云短信】手机号码错误，发送失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，手机号码错误!");
            }
            DefaultProfile profile = DefaultProfile.getProfile("default", account, password);
            IAcsClient client = new DefaultAcsClient(profile);
            CommonRequest request = new CommonRequest();
            request.setSysMethod(MethodType.POST);
            request.setSysDomain("dysmsapi.aliyuncs.com");
            request.setSysVersion("2017-05-25");
            request.setSysAction("SendSms");
            // 要发送到的手机号
            request.putQueryParameter("PhoneNumbers", mobile);
            // 短信签名名称。请在控制台签名管理页面签名名称一列查看。 说明 必须是已添加、并通过审核的短信签名。
            request.putQueryParameter("SignName", smsSign);
            // 短信模板ID。请在控制台模板管理页面模板CODE一列查看。 说明 必须是已添加、并通过审核的短信签名；且发送国际/港澳台消息时，请使用国际/港澳台短信模版。
            request.putQueryParameter("TemplateCode", templateCode);
            // 短信模板变量对应的实际值，JSON格式。 说明 如果JSON中需要带换行符，请参照标准的JSON协议处理。 可选
            if (StringUtils.isNotBlank(templateParam)){
                request.putQueryParameter("TemplateParam", templateParam);
            }
            CommonResponse response = client.getCommonResponse(request);
            //阿里云返回内容
            String resultStr = response.getData();
            if (StringUtils.isBlank(resultStr)) {
                log.info("【阿里云短信】发送失败，阿里云返回值为空, 手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，阿里云返回值为空");
            }
            JSONObject jsonObject = JSON.parseObject(resultStr);
            log.info("【阿里云短信】短信发送结果返回, 手机号码：" + mobile + ",发送模板CODE： " + templateCode + ",返回值：" + resultStr);
            String successStr = jsonObject.getString("Code");
            if ("OK".equals(successStr)) {
                log.info("【阿里云短信】发送成功, 手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.ok("发送成功【阿里云】");
            }
            String message = jsonObject.getString("Message");
            log.info("【阿里云短信】发送失败, 手机号码：" + mobile + ",发送模板CODE： " + templateCode);
            return Result.fail("发送失败，" + message);
        } catch (Exception e) {
            log.error("【阿里云短信】发送出现异常, mobile={}, 模板CODE={}", mobile, templateCode, e);
            return Result.fail(ErrorCodes.SMS_REQUEST_ERROR);
        }
    }
}